GPU インスタンシングを使用して、数千個のオブジェクトを同時に描画する方法を学びます。
シーンの構築
パーティクルのインスタンシング
GPU は並列計算に優れているため、数千、数百万のパーティクルを同時に描画することができます。これを実現する手法が GPU インスタンシング (GPU Instancing) です。
GPU インスタンシングでは、GPU に対して同じオブジェクト(モデル)のコピーを複数描画するように指示します。各コピーにはユニークな ID(0 から n-1)が割り当てられます。この ID に基づいて、各インスタンスの位置を決定できます。例えば、各オブジェクトを座標 [ID, 0, 0] に配置すれば、X 軸に沿った一列の並びが出来上がります。
p5.js では、endShape や model のオプション引数としてインスタンシングを利用できます。これにはカスタムシェーダーが必要です。ここでは、model を使用し、球体のジオメトリを構築してみましょう。
particleModel = buildGeometry(() => sphere(10, 2, 4));まずは、baseColorShader() を使用して、インスタンスを X 軸方向に等間隔で並べてみます。
スケッチのソースコードを見てみましょう:
let instancingShader;
let instancingStrokeShader;
let particleModel;
function instancingCallback() {
getWorldInputs((inputs) => {
// インスタンス ID に基づいて各インスタンスをオフセットします
inputs.position.x += instanceID() * 20;
// パーティクルを画面の左側に移動します
inputs.position.x -= 150;
return inputs;
});
}
async function setup() {
createCanvas(300, 300, WEBGL);
pixelDensity(1);
particleModel = buildGeometry(() => sphere(10, 10, 2));
instancingShader = baseColorShader().modify(instancingCallback);
instancingStrokeShader = baseStrokeShader().modify(instancingCallback);
}
function draw() {
background(0);
orbitControl();
shader(instancingShader);
strokeShader(instancingStrokeShader);
model(particleModel, 16);
}getWorldInputs() コールバックは、現在の頂点に関するデータ(position、normal、texCoord、color)を含む inputs 構造体を受け取ります:
getWorldInputs((inputs) => {
// 各インスタンスを ID に応じてオフセットします
inputs.position.x += instanceID() * 20;
// パーティクルを画面の左側に移動します
inputs.position.x -= 150;
return inputs;
});「ワールド (world)」という単語は、これが JavaScript 側で適用された translate() や scale() などの変換の後に実行されることを示しています。
License
Original URL: https://beta.p5js.org/tutorials/intro-to-p5-strands/
License: MIT License
Copyright (c) 2015-present p5.js contributors & The Processing Foundation